package com.dhcc.DRGsHosp.facade.impl;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

import javax.inject.Named;

import org.apache.commons.beanutils.PropertyUtils;
import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;

import com.dhcc.DRGsHosp.application.DrgServiceGroupApplication;
import com.dhcc.DRGsHosp.application.DrgsIndexCalApplication;
import com.dhcc.DRGsHosp.application.GroupingLogApplication;
import com.dhcc.DRGsHosp.application.PatientDrgApplication;
import com.dhcc.DRGsHosp.application.ReDisGroupApplication;
import com.dhcc.DRGsHosp.core.domain.GroupingLog;
import com.dhcc.DRGsHosp.core.domain.GroupingLogPrimary;
import com.dhcc.DRGsHosp.core.domain.OtherGroupingLogPrimary;
import com.dhcc.DRGsHosp.core.domain.OtherGroupingResult;
import com.dhcc.DRGsHosp.core.domain.PatientDrg;
import com.dhcc.DRGsHosp.core.domain.PatientDrgPrimary;
import com.dhcc.DRGsHosp.facade.GroupServiceFacade;
import com.dhcc.DRGsHosp.infra.util.DrgsIndex;
import com.dhcc.DRGsHosp.infra.util.GlobalData;
import com.dhcc.DRGsHosp.infra.util.NotInGroupReasonUtil;
import com.dhcc.DRGsHosp.infra.util.StringUtils;
@Named("groupServiceFacadeImplWY20170823")
public class GroupServiceFacadeImpl implements GroupServiceFacade{

	@Autowired
	private DrgServiceGroupApplication drgServiceGroupApplication;
	@Autowired 
	private ReDisGroupApplication reDisGroupApplication ;
	@Autowired
    private DrgsIndexCalApplication  drgsIndexCalApplication;
	@Autowired
	private GroupingLogApplication groupingLogApplication;
	@Autowired
	private PatientDrgApplication patientDrgApplication ;
	
	@Override
	public Map<String, Object> dataGenerate(Map<String, Object> mrInfoMap,String verDesc,String isMatch,String groupMatchDia,String groupMatchOper) {
		if(!verDesc.equals("")){
			Map<String, Object> mrInfo=new HashMap<>();
			if(verDesc!=null&&verDesc.indexOf("北京2016版")>=0){
				mrInfo=dataGenerate2016(mrInfoMap,isMatch, groupMatchDia, groupMatchOper);
			}else{
				mrInfo=dataGenerate2015(mrInfoMap,isMatch,groupMatchDia, groupMatchOper);
				mrInfo.put("ver", verDesc);
			}
			return mrInfo;
		}else{
			return null;
		}
	}
	/**
	 * 
	 *  dataGenerate2016.  
	 *  @Description：数据组装 2016版分组器
	 *  @Author WENYI
	 *  @param mrInfoMap
	 *  @param isMatch
	 *  @param groupMatchDia
	 *  @param groupMatchOper
	 *  @return 
	 *  @Date:2018年11月14日上午10:53:39
	 */
	private Map<String, Object> dataGenerate2016(Map<String, Object> mrInfoMap,String isMatch,String groupMatchDia,String groupMatchOper){
		//获取配置的手术编码
		String operVersion = GlobalData.sysConfig.get("OPER_VERSION");
		String icdOperVersion="OT";
		if(StringUtils.hasLength(operVersion)){
			icdOperVersion=operVersion.contains("BJ")?"BJ":operVersion.contains("CN")?"CN":"OT";
		}
		String diaCode=mrInfoMap.get("DISEASE_CODE")==null?null:mrInfoMap.get("DISEASE_CODE").toString();
		String reg = "^(-?\\d+)(\\.\\d+)?$";
		Pattern p = Pattern.compile(reg); //用于判断是否为浮点数
		Map<String, Object> mrInfo=new HashMap<>();
		mrInfo.put("B_WT4_V1_ID", (int)((Math.random()*9+1)*100000)+"");//随机生成6位数字代替病案号
		mrInfo.put("AGE", (mrInfoMap.get("AGE")==null||!p.matcher(mrInfoMap.get("AGE").toString()).find())?0:Double.valueOf(mrInfoMap.get("AGE").toString()).intValue());//年龄
		mrInfo.put("GENDER", mrInfoMap.get("GENDER")!=null?("1".equals(mrInfoMap.get("GENDER").toString())?"男":("2".equals(mrInfoMap.get("GENDER").toString())?"女":"")):"");//性别
		mrInfo.put("TOTAL_EXPENSE", (mrInfoMap.get("TOTAL_EXPENSE")==null||!p.matcher(mrInfoMap.get("TOTAL_EXPENSE").toString()).find())?null:Double.valueOf(mrInfoMap.get("TOTAL_EXPENSE").toString()));//总费用
		mrInfo.put("DISEASE_CODE", StringUtils.addXXForDiagCode(diaCode)+"");
		mrInfo.put("ACCTUAL_DAYS", (mrInfoMap.get("ACCTUAL_DAYS")==null||!p.matcher(mrInfoMap.get("ACCTUAL_DAYS").toString()).find())?null:Double.valueOf(mrInfoMap.get("ACCTUAL_DAYS").toString()).intValue());//住院天数
		mrInfo.put("SF0100", (mrInfoMap.get("SF0100")==null||!p.matcher(mrInfoMap.get("SF0100").toString()).find())?-1:Double.valueOf(mrInfoMap.get("SF0100").toString()).intValue());
		mrInfo.put("SF0102", (mrInfoMap.get("SF0102")==null||!p.matcher(mrInfoMap.get("SF0102").toString()).find())?-1:Double.valueOf(mrInfoMap.get("SF0102").toString()).intValue());
		mrInfo.put("SF0104", (mrInfoMap.get("SF0104")==null||!p.matcher(mrInfoMap.get("SF0104").toString()).find())?-1:Double.valueOf(mrInfoMap.get("SF0104").toString()).intValue());
		mrInfo.put("SF0108", (mrInfoMap.get("SF0108")==null||!p.matcher(mrInfoMap.get("SF0108").toString()).find())?-1:Double.valueOf(mrInfoMap.get("SF0108").toString()).intValue());
		mrInfo.put("CASE_ID", mrInfoMap.get("CASE_ID")==null?"":mrInfoMap.get("CASE_ID")+"");//首页ID
		//判断是否需要ICD对照--主诊断
		if(diaCode!=null){
			if("1".equals(isMatch)){
				//查询对照的ICD编码
				String diagMatch=getDiagMatchResult(diaCode, groupMatchDia, groupMatchOper, true);
				if(diagMatch!=null){
					mrInfo.put("DISEASE_CODE", StringUtils.addXXForDiagCode(diagMatch));
				}else {
					mrInfo.put("DISEASE_CODE", StringUtils.addXXForDiagCode(diaCode));
				}
			}else{
				//规范诊断编码
				mrInfo.put("DISEASE_CODE", StringUtils.addXXForDiagCode(diaCode));
			}
		}
		
		//其他诊断
		@SuppressWarnings("unchecked")
		List<String> diagList =mrInfoMap.get("DIAGS_CODE")==null?null:(List<String>)mrInfoMap.get("DIAGS_CODE");
		if(diagList!=null&&!diagList.isEmpty()){
			List<String> diagStr=new ArrayList<>();
			for (String diag : diagList) {
				if(diag!=null){
					if("1".equals(isMatch)){//判断是否需要对照
						//查询对照的ICD编码
						String diagMatch=getDiagMatchResult(diag, groupMatchDia, groupMatchOper, true);
						if(diagMatch!=null){
							diagStr.add(StringUtils.addXXForDiagCode(diagMatch));
						}else {
							diagStr.add(StringUtils.addXXForDiagCode(diag));
						}
					}else{
						//如果不需要ICD对照，则将原有的编码规范后添加到List
						diagStr.add(StringUtils.addXXForDiagCode(diag));
					}
					
				}
			}
			mrInfo.put("diags_code", diagStr.toArray());
		}
				
		//获取手术信息
		@SuppressWarnings("unchecked")
		List<String> operList = mrInfoMap.get("OPERS_CODE")==null?null:(List<String>)mrInfoMap.get("OPERS_CODE");
		if(operList!=null&&!operList.isEmpty()){
			List<String> operStr=new ArrayList<>();
			for (String oper : operList) {
				if(oper!=null){
					if("1".equals(isMatch)){//对照
						//查询对照的ICD编码
						String operMatch=getOperMatchResult(oper, groupMatchDia, groupMatchOper,icdOperVersion, true);
						if(operMatch!=null){
							//对照上了说明该编码已经变为北京临床编码，所以走‘BJ’
							operStr.add(StringUtils.addZeroForOperCode(operMatch,"BJ"));//手术操作补零处理
						}else {
							//若没对照上了说明该编码不变，所以走系统配置中ICD版本中的手术版本配置
							operStr.add(StringUtils.addZeroForOperCode(oper,icdOperVersion));//手术操作补零处理
						}
					}else{
						//如果不需要ICD对照，则将原有的编码规范后添加到List
						operStr.add(StringUtils.addZeroForOperCode(oper,icdOperVersion));//手术操作补零处理
					}
				}
			}
			mrInfo.put("opers_code", operStr.toArray());
		}
		return mrInfo;
	}
	/**
	 * 
	 *  getDiagMatch.  
	 *  @Description：获取诊断的对照编码
	 *  @Author WENYI
	 *  @param diagCode
	 *  @param groupMatchDia
	 *  @param groupMatchOper
	 *  @param recursion 是否递归，实际应用时，即在第一次没有查到对应的对照编码后，是否需要将原始编码规范后，再查对照关系
	 *  @return 
	 *  @Date:2018年11月14日上午10:46:28
	 */
	private String getDiagMatchResult(String diagCode,String groupMatchDia,String groupMatchOper,boolean recursion){
		String result=null;
		List<Object[]> matchList = drgServiceGroupApplication.getMatchResult(diagCode,"D",groupMatchDia, groupMatchOper);
		if(!matchList.isEmpty()&&matchList.get(0)[2]!=null){
			result=matchList.get(0)[2].toString();
		}else if (recursion) {
			result=getDiagMatchResult(StringUtils.addXXForDiagCode(diagCode),groupMatchDia, groupMatchOper,false);
		}
		return result;
	}
	/**
	 * 
	 *  getOperMatchResult.  
	 *  @Description：
	 *  @Author WENYI
	 *  @param operCode
	 *  @param groupMatchDia
	 *  @param groupMatchOper
	 *  @param icdOperVersion
	 *  @param recursion 是否递归，实际应用时，即在第一次没有查到对应的对照编码后，是否需要将原始编码规范后，再查对照关系
	 *  @return 
	 *  @Date:2018年11月14日上午11:19:25
	 */
	private String getOperMatchResult(String operCode,String groupMatchDia,String groupMatchOper,String icdOperVersion,boolean recursion){
		String result=null;
		List<Object[]> matchList = drgServiceGroupApplication.getMatchResult(operCode,"O",groupMatchDia, groupMatchOper);
		if(!matchList.isEmpty()&&matchList.get(0)[2]!=null){
			result=matchList.get(0)[2].toString();
		}else if (recursion) {
			result=getOperMatchResult(StringUtils.addZeroForOperCode(operCode,icdOperVersion),groupMatchDia, groupMatchOper,icdOperVersion,false);
		}
		return result;
	}
	/**
	 * 
	 *  dataGenerate2015.  
	 *  @Description：数据组装 2015版分组器
	 *  @Author WENYI
	 *  @param mrInfoMap
	 *  @param isMatch
	 *  @param groupMatchDia
	 *  @param groupMatchOper
	 *  @return 
	 *  @Date:2018年11月14日上午10:53:20
	 */
	private Map<String, Object> dataGenerate2015(Map<String, Object> mrInfoMap,String isMatch,String groupMatchDia,String groupMatchOper){
		//获取配置的手术编码
		String operVersion = GlobalData.sysConfig.get("OPER_VERSION");
		String icdOperVersion="OT";
		if(StringUtils.hasLength(operVersion)){
			icdOperVersion=operVersion.contains("BJ")?"BJ":operVersion.contains("CN")?"CN":"OT";
		}
		Map<String, Object> mrInfo=new HashMap<>();
		String diaCode=mrInfoMap.get("DISEASE_CODE")==null?null:mrInfoMap.get("DISEASE_CODE").toString();
		String reg = "^(-?\\d+)(\\.\\d+)?$";
		Pattern p = Pattern.compile(reg); //用于判断是否为浮点数
		mrInfo.put("CASE_ID", mrInfoMap.get("CASE_ID")==null?"":mrInfoMap.get("CASE_ID")+"");//首页ID
		mrInfo.put("AGE", (mrInfoMap.get("AGE")==null||!p.matcher(mrInfoMap.get("AGE").toString()).find())?0:Double.valueOf(mrInfoMap.get("AGE").toString()).intValue());
		mrInfo.put("GENDER", mrInfoMap.get("GENDER")!=null?("1".equals(mrInfoMap.get("GENDER").toString())?"男":("2".equals(mrInfoMap.get("GENDER").toString())?"女":"")):"");
		mrInfo.put("TOTAL_EXPENSE", (mrInfoMap.get("TOTAL_EXPENSE")==null||!p.matcher(mrInfoMap.get("TOTAL_EXPENSE").toString()).find())?null:Double.valueOf(mrInfoMap.get("TOTAL_EXPENSE").toString()));
		mrInfo.put("DISEASE_CODE", StringUtils.addXXForDiagCode(diaCode)+"");
		mrInfo.put("ACCTUAL_DAYS", (mrInfoMap.get("ACCTUAL_DAYS")==null||!p.matcher(mrInfoMap.get("ACCTUAL_DAYS").toString()).find())?null:Double.valueOf(mrInfoMap.get("ACCTUAL_DAYS").toString()).intValue());
		mrInfo.put("SF0100",(mrInfoMap.get("SF0100")==null||!p.matcher(mrInfoMap.get("SF0100").toString()).find())?null:Double.valueOf(mrInfoMap.get("SF0100").toString()).intValue());
		mrInfo.put("SF0102", (mrInfoMap.get("SF0102")==null||!p.matcher(mrInfoMap.get("SF0102").toString()).find())?null:Double.valueOf(mrInfoMap.get("SF0102").toString()).intValue());
		mrInfo.put("SF0104", (mrInfoMap.get("SF0104")==null||!p.matcher(mrInfoMap.get("SF0104").toString()).find())?null:Double.valueOf(mrInfoMap.get("SF0104").toString()).intValue());
		mrInfo.put("SF0108", (mrInfoMap.get("SF0108")==null||!p.matcher(mrInfoMap.get("SF0108").toString()).find())?null:Double.valueOf(mrInfoMap.get("SF0108").toString()).intValue());
		//判断是否需要ICD对照--主诊断
		if(diaCode!=null){
			if("1".equals(isMatch)){
				//查询对照的ICD编码
				String diagMatch=getDiagMatchResult(diaCode, groupMatchDia, groupMatchOper, true);
				if(diagMatch!=null){
					mrInfo.put("DISEASE_CODE", StringUtils.addXXForDiagCode(diagMatch));
				}else {
					mrInfo.put("DISEASE_CODE", StringUtils.addXXForDiagCode(diaCode));
				}
			}else{
				//规范诊断编码
				mrInfo.put("DISEASE_CODE", StringUtils.addXXForDiagCode(diaCode));
			}
		}
		//其他诊断
		@SuppressWarnings("unchecked")
		List<String> diagList =mrInfoMap.get("DIAGS_CODE")==null?null:(List<String>)mrInfoMap.get("DIAGS_CODE");
		List<Map<String, String>> diagFinalList =new ArrayList<>();
		if(diagList!=null&&!diagList.isEmpty()){
			for (String diag : diagList) {
				if(diag!=null){
					Map<String, String> m = new HashMap<String, String>();
					if("1".equals(isMatch)){//判断是否需要对照
						//查询对照的ICD编码
						String diagMatch=getDiagMatchResult(diag, groupMatchDia, groupMatchOper, true);
						if(diagMatch!=null){
							m.put("code", StringUtils.addXXForDiagCode(diagMatch));
							diagFinalList.add(m);
						}else {
							m.put("code", StringUtils.addXXForDiagCode(diag));
							diagFinalList.add(m);
						}
					}else{
						//如果不需要ICD对照，则将原有的编码规范后添加到List
						m.put("code", StringUtils.addXXForDiagCode(diag));
						diagFinalList.add(m);
					}
					
				}
			}
			mrInfo.put("diags", diagFinalList);
		}
		
		//获取手术信息
		@SuppressWarnings("unchecked")
		List<String> operList = mrInfoMap.get("OPERS_CODE")==null?null:(List<String>)mrInfoMap.get("OPERS_CODE");
		List<Map<String, String>> operFinalList = new ArrayList<Map<String,String>>();
		if(operList!=null&&!operList.isEmpty()){
			for (String oper : operList) {
				if(oper!=null){
					Map<String, String> m = new HashMap<String, String>();
					if("1".equals(isMatch)){//对照
						//查询对照的ICD编码
						String operMatch=getOperMatchResult(oper, groupMatchDia, groupMatchOper,icdOperVersion, true);
						if(operMatch!=null){
							//对照上了说明该编码已经变为北京临床编码，所以走‘BJ’
							m.put("code", StringUtils.addZeroForOperCode(operMatch,"BJ"));//手术操作补零处理
							operFinalList.add(m);
						}else {
							//若没对照上了说明该编码不变，所以走系统配置中ICD版本中的手术版本配置
							m.put("code", StringUtils.addZeroForOperCode(oper,icdOperVersion));//手术操作补零处理
							operFinalList.add(m);
						}
					}else{
						//如果不需要ICD对照，则将原有的编码规范后添加到List
						m.put("code", StringUtils.addZeroForOperCode(oper,icdOperVersion));
						operFinalList.add(m);
					}
				}
			}
			mrInfo.put("opers", operFinalList);
		}
		return mrInfo;
	}
	@Override
	public Map<String, Object> group(Map<String, Object> mrInfoMap,String groupUrl,String groupVer,boolean groupAgain) {
		ObjectMapper objectMapper = new ObjectMapper();
		String json="";
		StringBuilder sb = new StringBuilder();
		Map<String, Object> resultMap=new HashMap<>();
		try {
			json=objectMapper.writeValueAsString(mrInfoMap);
//			System.err.println(json);
			/*********************分组器调用*****************************/	
			URL url = new URL("http://" + groupUrl);
			HttpURLConnection con = (HttpURLConnection) url.openConnection();
			con.setDoOutput(true);
			con.setDoInput(true);
			con.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
			con.setRequestProperty("Accept", "application/json");
			con.setRequestMethod("POST");

			OutputStream os = con.getOutputStream();
			os.write(json.getBytes("UTF-8"));
			os.flush();
			os.close();
			int HttpResult = con.getResponseCode();
			if (HttpResult == HttpURLConnection.HTTP_OK) {
				BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream(), "UTF-8"));
				String line = null;
				while ((line = br.readLine()) != null) {
					sb.append(line + "\n");
				}
				br.close();
				System.out.println("" + sb.toString());
			} else {
				System.out.println(con.getResponseMessage());
			}
			if(StringUtils.hasLength(sb)){
				resultMap=objectMapper.readValue(sb.toString(), Map.class);
				//判断是否需要再分组
				if (groupAgain&&(resultMap.get("drg").toString().matches("^\\w{1,2}QY$")||resultMap.get("drg").toString().matches("^\\d{4}$"))) {
					//获取标杆
					String groupSchemeBenchType = drgsIndexCalApplication.getConfigValueByCode("groupScheme_benchType");
					String benchType=null;
					if(StringUtils.hasLength(groupSchemeBenchType)) {
						String gbStr[]=groupSchemeBenchType.split("θ");	
						if(gbStr.length>=2){
							benchType=gbStr[1];
						}
					}
					Map<String,Object> reGroupResult=null;
					if(groupVer!=null&&groupVer.indexOf("北京2016版")>=0){
						reGroupResult = reGroupBj2016(mrInfoMap,groupUrl,groupVer,benchType);
					} else {
						reGroupResult = reGroupBjBefore2016(mrInfoMap,groupUrl,groupVer,benchType);
					}
					// 如果reGoupResult不为null，并将原来的结果覆盖
					if(reGroupResult != null) {
						resultMap=reGroupResult;
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
		return resultMap;
	}
	/**
	 * 
	 *  reGroupBj2016.  
	 *  @Description：再分组 2016版分组器
	 *  @Author WENYI
	 *  @param mrInfoMap
	 *  @param groupAddr
	 *  @param groupVer
	 *  @param benchType
	 *  @return 
	 *  @Date:2018年11月15日下午4:23:20
	 */
	private Map<String,Object> reGroupBj2016(Map<String, Object> mrInfoMap, String groupAddr,String groupVer,String benchType) {
		// 病人信息 
		String pmainindex=mrInfoMap.get("CASE_ID").toString() ;
		String diagMain = mrInfoMap.get("DISEASE_CODE") == null ? "" : (String)mrInfoMap.get("DISEASE_CODE");
		String redisId = pmainindex + "_" + diagMain  ;
		String drgCode = null ;
		// 所有再分组入组结果 
		List<Map<String,Object>> allResultMapList = new ArrayList<>() ;
		// 所有再分组信息
		List<Map<String,Object>> allReGroupInfoList = new ArrayList<>() ;
		// 2016分组器版本的其他诊断
		Object[] diagOtherArray = null ;
		if(mrInfoMap.get("diags_code") != null) {
			diagOtherArray = (Object[])mrInfoMap.get("diags_code") ;
		} 
		
		if(diagOtherArray!=null) {
			for(int i = 0 ; i < diagOtherArray.length ; i++) {
				Map<String,Object> reGroupInfo = new HashMap<>() ;
				// 再分组结果
				mrInfoMap.put("DISEASE_CODE", diagOtherArray[i]) ;
				Object[] diagOtherArrayTemp = new Object[diagOtherArray.length] ;
				try {
				// 对象复制
				PropertyUtils.copyProperties(diagOtherArrayTemp, diagOtherArray);
				} catch (IllegalAccessException e) {
					e.printStackTrace();
				} catch (InvocationTargetException e) {
					e.printStackTrace();
				} catch (NoSuchMethodException e) {
					e.printStackTrace();
				}
				diagOtherArrayTemp[i] = diagMain  ;
				mrInfoMap.put("DIAGS_CODE", diagOtherArrayTemp) ;
				Map<String,Object> resultMap = group(mrInfoMap,groupAddr,groupVer,false);
				
				redisId = pmainindex + "_" +diagOtherArray[i] + "_" + (i+1) ;
				reGroupInfo.put("redisId", redisId) ;
				reGroupInfo.put("pmainindex", pmainindex) ;
				reGroupInfo.put("diasisCode", diagOtherArray[i]) ;
				reGroupInfo.put("verCode", GlobalData.sysConfig.get("GROUP_VER")) ;
				reGroupInfo.put("isCheck", 0) ;
				reGroupInfo.put("diasisOrder", i+1) ;
				reGroupInfo.put("log",resultMap.get("log")==null?"":resultMap.get("log")) ;
				reGroupInfo.put("index", i) ;
				resultMap.put("index", i) ;
				Double weight = null ;
				// 如果入组了则查询病组对应的权重
				if (resultMap.get("drg").toString().matches("^\\w{1,2}QY$")||resultMap.get("drg").toString().matches("^\\d{4}$")) {
					reGroupInfo.put("drgCode", drgCode) ;
					reGroupInfo.put("weight", weight) ;
				} else {
					// 入组
					weight = reDisGroupApplication.findWeightByDrgCodeAndGroupVer(resultMap.get("drg").toString(),GlobalData.sysConfig.get("GROUP_VER"),benchType) ;
					reGroupInfo.put("drgCode", resultMap.get("drg").toString()) ;
					reGroupInfo.put("weight", weight) ;
					allResultMapList.add(resultMap) ;
				}
				allReGroupInfoList.add(reGroupInfo);
			}
		}
		// 对入组结果按照drg权重进行降续排列,权重相同时按诊断顺序升序排列，取权重最大的分组结果返回
		Collections.sort(allReGroupInfoList, new Comparator<Map<String,Object>>() {
			@Override
			public int compare(Map<String, Object> m1, Map<String, Object> m2) {
				int returnValue = 1;
				if(null!=m1 && null!=m2){
					double d1 = 0;
					double d2 = 0;
					// 将未入组的分组结果排在后面
					if(m1.get("drgCode")==null && m2.get("drgCode") == null ) {
						return -1 ;
					}
					if(m1.get("drgCode")==null&& m2.get("drgCode") != null){
						return 1 ;
					}
					if(m1.get("drgCode")!=null&& m2.get("drgCode") == null){
						return -1 ;
					}
					// 权重降序
					d1 = m1.get("weight")==null?0:Double.parseDouble(m1.get("weight").toString());
					d2 = m2.get("weight")==null?0:Double.parseDouble(m2.get("weight").toString());
	            	if(d1>d2) {
	                	returnValue = -1 ;
	                } else if(d1<d2) {
	                	returnValue = 1 ;
	                } else {
	                	// 诊断顺序升序
	                	d1 = m1.get("diasisOrder")==null?0:Double.parseDouble(m1.get("diasisOrder").toString());
						d2 = m2.get("diasisOrder")==null?0:Double.parseDouble(m2.get("diasisOrder").toString());
						if(d1>d2) {
							returnValue = 1 ;
						} else if(d1<d2) {
							returnValue = -1 ;
						} else {
							returnValue = 0 ;
						}
	                }
		        }
		        return returnValue;
			}
		});
		if(allResultMapList.size() > 0) {
			// 保存再分组结果（包括入组和未入组）
			allReGroupInfoList.get(0).put("isCheck", 1) ;
			reDisGroupApplication.saveReDisGroupList(allReGroupInfoList) ;
			// 获取最高权重病组对应的分组结果
			for (Map<String,Object> map : allResultMapList) {
				// 入组权重最大对应的顺序编号
				String index = allReGroupInfoList.get(0).get("index").toString() ;
				// 根据诊断顺序查询相应的
				if(map.get("index").toString().equals(index)) {
					return map ;
				} 
			}
		} 
		return null ;
	}
	/**
	 * 
	 *  reGroupBjBefore2016.  
	 *  @Description：再分组功能 2015版
	 *  @Author WENYI
	 *  @param mrInfoMap
	 *  @param groupAddr
	 *  @param groupVer
	 *  @param benchType
	 *  @return 
	 *  @Date:2018年11月15日下午4:23:45
	 */
	private Map<String, Object> reGroupBjBefore2016(Map<String, Object> mrInfoMap, String groupAddr,String groupVer,String benchType) {
		// 病人信息 
		String pmainindex=mrInfoMap.get("CASE_ID").toString() ;
		String diagMain = mrInfoMap.get("DISEASE_CODE") == null ? "" : (String)mrInfoMap.get("DISEASE_CODE");
		String redisId = pmainindex + "_" + diagMain  ;
		String drgCode = null ;
		// 所有再分组入组结果 
		List<Map<String,Object>> allResultMapList = new ArrayList<>() ;
		// 所有再分组入组信息
		List<Map<String,Object>> allReGroupInfoList = new ArrayList<>() ;
		// 2016之前分组器版本的其他诊断
		List<Map<String,Object>> diagOtherList = null ;
		if(mrInfoMap.get("diags") != null) {
			diagOtherList = (List<Map<String,Object>>)mrInfoMap.get("diags") ;
		}
		if(diagOtherList!=null) {
			for(int i = 0 ; i < diagOtherList.size() ; i++) {
				Map<String,Object> reGroupInfo = new HashMap<>() ;
				// 再分组结果
				mrInfoMap.put("DISEASE_CODE", diagOtherList.get(i).get("code")) ;
				List<Map<String,Object>> diagOtherListTemp = new ArrayList<>() ;
				diagOtherListTemp = (List<Map<String, Object>>) DrgsIndex.copyPropertiesObj(diagOtherList) ;
//				diagOtherListTemp = (List<Map<String,Object>>)deepClone(diagOtherList);
				diagOtherListTemp.get(i).put("code", diagMain) ;
				mrInfoMap.put("diags", diagOtherListTemp) ;
				//是否再分组，传入false
				Map<String,Object> resultMap  = group(mrInfoMap,groupAddr,groupVer,false) ;
				redisId = pmainindex + "_" +diagOtherList.get(i).get("code") + "_" + (i+1) ;
				reGroupInfo.put("redisId", redisId) ;
				reGroupInfo.put("pmainindex", pmainindex) ;
				reGroupInfo.put("diasisCode", diagOtherList.get(i).get("code")) ;
				reGroupInfo.put("verCode", GlobalData.sysConfig.get("GROUP_VER")) ;
				reGroupInfo.put("isCheck", 0) ;
				reGroupInfo.put("diasisOrder", i+1) ;
				reGroupInfo.put("log",resultMap.get("log")==null?"":resultMap.get("log").toString()) ;
				reGroupInfo.put("index", i) ;
				resultMap.put("index", i) ;
				Double weight = null ;
				// 如果入组了则查询病组对应的权重
				if (resultMap.get("drg").toString().matches("^\\w{1,2}QY$")||resultMap.get("drg").toString().matches("^\\d{4}$")) {
					reGroupInfo.put("drgCode", drgCode) ;
					reGroupInfo.put("weight", weight) ;
				} else {
					// 入组
					weight = reDisGroupApplication.findWeightByDrgCodeAndGroupVer(resultMap.get("drg").toString(),GlobalData.sysConfig.get("GROUP_VER"),benchType) ;
					reGroupInfo.put("drgCode", resultMap.get("drg").toString()) ;
					reGroupInfo.put("weight", weight) ;
					allResultMapList.add(resultMap) ;
				}
				allReGroupInfoList.add(reGroupInfo) ;
			}
		}
		// 对入组结果按照drg权重进行降续排列,权重相同时按诊断顺序升序排列，取权重最大的分组结果返回
		Collections.sort(allReGroupInfoList, new Comparator<Map<String,Object>>() {
			@Override
			public int compare(Map<String, Object> m1, Map<String, Object> m2) {
				int returnValue = 1;
				if(null!=m1 && null!=m2){
					double d1 = 0;
					double d2 = 0;
					// 将未入组的分组结果排在后面
					if(m1.get("drgCode")==null && m2.get("drgCode") == null ) {
						return -1 ;
					}
					if(m1.get("drgCode")==null&& m2.get("drgCode") != null){
						return 1 ;
					}
					if(m1.get("drgCode")!=null&& m2.get("drgCode") == null){
						return -1 ;
					}
					// 权重降序
					d1 = m1.get("weight")==null?0:Double.parseDouble(m1.get("weight").toString());
					d2 = m2.get("weight")==null?0:Double.parseDouble(m2.get("weight").toString());
	            	if(d1>d2) {
	                	returnValue = -1 ;
	                } else if(d1<d2) {
	                	returnValue = 1 ;
	                } else {
	                	// 诊断顺序升序
	                	d1 = m1.get("diasisOrder")==null?0:Double.parseDouble(m1.get("diasisOrder").toString());
						d2 = m2.get("diasisOrder")==null?0:Double.parseDouble(m2.get("diasisOrder").toString());
						if(d1>d2) {
							returnValue = 1 ;
						} else if(d1<d2) {
							returnValue = -1 ;
						} else {
							returnValue = 0 ;
						}
	                }
		        }
		        return returnValue;
			}
		});
		if(allResultMapList.size() > 0) {
			// 保存再分组结果（包括入组和未入组）
			allReGroupInfoList.get(0).put("isCheck", 1) ;
			reDisGroupApplication.saveReDisGroupList(allReGroupInfoList) ;
			// 获取最高权重病组对应的分组结果
			for (Map<String,Object> map : allResultMapList) {
				// 入组权重最大对应的顺序编号
				String index = allReGroupInfoList.get(0).get("index").toString() ;
				// 根据诊断顺序查询相应的分组结果
				if(map.get("index").toString().equals(index)) {
					return map ;
				} 
			}
		} 
		return null ;
	}
	
	@Override
	public Map<String,String> groupResultLogSave(Map<String, Object> mrInfoMap, Map<String, Object> resultMap,String groupVerCode,String groupVerDesc,String verRegion,String isICDMatch){
		Map<String,String> result=new HashMap<String,String>();
		if(groupVerDesc!=null&&groupVerDesc.indexOf("北京2016版")>=0){
			result=groupResultLogSave2016(mrInfoMap,resultMap,groupVerCode,groupVerDesc,verRegion,isICDMatch);
		}
		else{
			result=groupResultLogSaveBefore2016(mrInfoMap,resultMap,groupVerCode,groupVerDesc,verRegion,isICDMatch);
		}
		return result;
	}
	/**
	 * 
	 *  groupResultLogSave2016.  
	 *  @Description：2016版分组结果和日志保存
	 *  @Author WENYI
	 *  @param mrInfoMap
	 *  @param resultMap
	 *  @param groupVerCode
	 *  @param groupVerDesc
	 *  @param verRegion
	 *  @param isICDMatch
	 *  @return 
	 *  @Date:2018年11月15日下午4:25:10
	 */
	private Map<String,String> groupResultLogSave2016(Map<String, Object> mrInfoMap, Map<String, Object> resultMap,String groupVerCode,String groupVerDesc,String verRegion,String isICDMatch){
		Map<String,String> result=new HashMap<String,String>();
		ObjectMapper mapper = new ObjectMapper();
		String json="";
		try {
			json=mapper.writeValueAsString(mrInfoMap);
			if(resultMap!=null){
				if(resultMap.get("log")!=null){
		    		String logs[]=resultMap.get("log").toString().split(";");
					List<String> logList=Arrays.asList(logs);
					resultMap.put("log", logList);
				}
				//开始保存数据
				String mrId=mrInfoMap.get("CASE_ID").toString();
				PatientDrgPrimary patientDrgPrimary=new PatientDrgPrimary();
				patientDrgPrimary.setParid(mrId);
				patientDrgPrimary.setVer_region(verRegion);
				PatientDrg patientDrg=new PatientDrg(patientDrgPrimary);//实体类
				boolean inCaseFlag=true;//入组标识
				if (resultMap.get("drg")!=null && (resultMap.get("drg").toString().matches("^\\w{1,2}QY$")||resultMap.get("drg").toString().matches("^\\d{4}$"))) {
					//如果drgCode为QY结尾则存为未分组
					patientDrg.setNotinCode(resultMap.get("drg")+"");
					inCaseFlag=false;
				} else {
					patientDrg.setPardrgCode(resultMap.get("drg")+"");//DRGs代码
					patientDrg.setMdc("MDC"+resultMap.get("drg").toString().substring(0, 1));
				}
				patientDrg.setVerCode(groupVerCode);
				//保存2016版新增分组结果
				OtherGroupingResult dr=new OtherGroupingResult();
				OtherGroupingLogPrimary drid = new OtherGroupingLogPrimary();
				drid.setMr_id(mrId);
				drid.setVer_code(groupVerCode);
				drid.setGr_isicd(isICDMatch);
				dr.setPkId(drid);
				dr.setOpersQy(resultMap.get("opers_qy")+"");
				dr.setOpersCode(resultMap.get("oper_code")+"");
				dr.setOpersAdrg(resultMap.get("opers_adrg")+"");
				dr.setMdcsMain(resultMap.get("mdcs_main")+"");
				dr.setMcc(resultMap.get("mcc")+"");
				dr.setError(resultMap.get("error")+"");
				dr.setDiagsCc(resultMap.get("diags_cc")+"");
				dr.setCc(resultMap.get("cc")+"");
				dr.setAdrgsDiag(resultMap.get("adrgs_diag")+"");
				dr.setAdrgsSurg(resultMap.get("adrgs_surg")+"");
				dr.setAdrgsPre(resultMap.get("adrgs_pre")+"");
				dr.setAdrgsOpermain(resultMap.get("adrgs_opermain")+"");
				dr.setAdrgsOper(resultMap.get("adrgs_oper")+"");
				dr.setAdrgsMedi(resultMap.get("adrgs_medi")+"");
				dr.setAdrgsMain(resultMap.get("adrgs_main")+"");
				dr.setErrorLog(resultMap.get("error_log")+"");
				dr.setGroupLog(resultMap.get("log")+"");
				drgServiceGroupApplication.creatOtherGroupingLog(dr);
				
				//保存分组日志分组日志
				resultMap.put("CASE_ID", mrId);//存入mr_id，保存日志时使用
				String notInReason=createGroupingLog(mrInfoMap,resultMap,inCaseFlag,groupVerCode,groupVerDesc,verRegion);//保存分组日志并返回未入组原因代码
				//保存的时候要更新
				patientDrg.setNotInReason(notInReason);
				patientDrgApplication.creatPatientDrg(patientDrg);
				result.put("error", "false");
				result.put("drgCode", resultMap.get("drg")+"");
			}
			else{
				errorInfoSave(json,"分组器调用异常，未返回分组结果");
				result.put("error", "true");
				result.put("errorLog", "分组器调用异常，未返回分组结果");
			}
		}
		catch (Exception e) {
			e.printStackTrace();
			result.put("error", "true");
			result.put("errorLog", e.toString());
			errorInfoSave(json,e.toString());
		}
		return result;
	}
	/**
	 * 
	 *  groupResultLogSaveBefore2016.  
	 *  @Description：2015版分组结果和日志保存
	 *  @Author WENYI
	 *  @param mrInfoMap
	 *  @param resultMap
	 *  @param groupVerCode
	 *  @param groupVerDesc
	 *  @param verRegion
	 *  @param isICDMatch
	 *  @return 
	 *  @Date:2018年11月15日下午4:26:13
	 */
	private Map<String,String> groupResultLogSaveBefore2016(Map<String, Object> mrInfoMap, Map<String, Object> resultMap,String groupVerCode,String groupVerDesc,String verRegion,String isICDMatch){
		Map<String,String> result=new HashMap<String,String>();
		ObjectMapper objectMapper = new ObjectMapper();
		String json="";
		try {
			json=objectMapper.writeValueAsString(mrInfoMap);
			if(resultMap!=null){
				//开始保存数据
				String mrId=mrInfoMap.get("CASE_ID").toString();
				PatientDrgPrimary patientDrgPrimary=new PatientDrgPrimary();
				patientDrgPrimary.setParid(mrId);
				patientDrgPrimary.setVer_region(verRegion);
				PatientDrg patientDrg=new PatientDrg(patientDrgPrimary);//实体类
		        boolean inCaseFlag=true;//入组标识
		        if (resultMap.get("drg")!=null && (resultMap.get("drg").toString().matches("^\\w{1,2}QY$")||resultMap.get("drg").toString().matches("^\\d{4}$"))) {
		        	patientDrg.setNotinCode(resultMap.get("drg")+"");
					inCaseFlag=false;
				} else {
					patientDrg.setPardrgCode(resultMap.get("drg")+"");//DRGs代码
					patientDrg.setMdc("MDC"+resultMap.get("drg").toString().substring(0, 1));
				}
		        
		        
				if (groupVerCode==null) {
					patientDrg.setVerCode("");
				}else {
					patientDrg.setVerCode(groupVerCode);
				}
				//保存分组日志
				resultMap.put("CASE_ID", mrId);//存入mr_id，保存日志时使用
				String notInReason=createGroupingLog(mrInfoMap,resultMap,inCaseFlag,groupVerCode,groupVerDesc,verRegion);//保存分组日志并返回未入组原因代码
				//保存的时候要更新
				patientDrg.setNotInReason(notInReason);
				patientDrgApplication.creatPatientDrg(patientDrg);
				result.put("error", "false");
				result.put("drgCode", resultMap.get("drg")+"");
			}
			else{
				errorInfoSave(json,"分组器调用异常，未返回分组结果");
				result.put("error", "true");
				result.put("errorLog", "分组器调用异常，未返回分组结果");
			}
		} catch (Exception e) {
			e.printStackTrace();
			result.put("error", "true");
			result.put("errorLog", e.toString());
			errorInfoSave(json,e.toString());
		}
		return result;
	}
	/**
	 * 
	 *  createGroupingLog.  
	 *  @Description：分组日志保存
	 *  @Author WENYI
	 *  @param mrInfoMap
	 *  @param s
	 *  @param inCaseFlag
	 *  @param groupVerCode
	 *  @param groupVerDesc
	 *  @param verRegion
	 *  @return 
	 *  @Date:2018年11月15日下午4:26:31
	 */
	private String createGroupingLog(Map<String, Object> mrInfoMap,Map<String, Object> s,boolean inCaseFlag,String groupVerCode,String groupVerDesc,String verRegion) {
		ObjectMapper objectMapper = new ObjectMapper();
		String mrId=s.get("CASE_ID").toString();
		//分组日志start
		GroupingLogPrimary groupingLogPrimary= new GroupingLogPrimary();
		GroupingLog groupingLog = new GroupingLog(groupingLogPrimary);
		groupingLogPrimary.setMr_adm(mrId);
		groupingLogPrimary.setVer_region(verRegion);
		
		groupingLog.setVerCode(groupVerCode);
		if (s.get("oper_code")!=null) {
			groupingLog.setGlOperCode(s.get("oper_code")+"");
		}
		if (s.get("oper_name")!=null) {
			groupingLog.setGlOperName(s.get("oper_name")+"");
		}
		String index = "";
		Class<GroupingLog> groupLogClass = GroupingLog.class;
        Field field = null;
        if(s.get("log")!=null){
        	@SuppressWarnings("unchecked")
			List<String> logList=(List<String>)s.get("log");
			List<String> indexList=new ArrayList<>();
        	for (String string :logList) {
        		string=string.replace(":", "：");//16版分组日志判断中的冒号用的英文，替换成中文冒号
        		index = string.replaceAll("^判断(\\d\\d)(\\.(\\d))?(\\.(\\d))?：.*$", "$1$3$5");
        		index = index.replaceAll("^判断(\\d)(\\.(\\d))?(\\.(\\d))?：.*$", "0$1$3$5");
        		try {
        			field = groupLogClass.getDeclaredField("glJ" + index);
        			field.setAccessible(true);
        			//处理判断01和02有两个的问题，用Ω连接
        			if(indexList.contains(index)){
        				Object temp=field.get(groupingLog);
        				field.set(groupingLog, (temp==null?"":temp.toString())+"Ω"+string);
        			}
        			else {
        				field.set(groupingLog, string);
					}
        			indexList.add(index);
        		} catch (Exception e) {
        			e.printStackTrace();
        		}
			}
        }
        String notInReason="0";//未入组原因代码
        if (!inCaseFlag) {
        	try {
				String notInReasonJson=NotInGroupReasonUtil.notInGroupReason(objectMapper.writeValueAsString(mrInfoMap),objectMapper.writeValueAsString(s),groupVerDesc);
				notInReason=DrgsIndex.notInReasonPharse(mrId,notInReasonJson);
        	}catch (Exception e) {
				e.printStackTrace();
				notInReason="o_other";
			}
		}
        groupingLog.setNotinreason(notInReason);
		// 保存分组日志信息
        groupingLogApplication.creatGroupingLog(groupingLog);
        return notInReason;
	}
	/**
	 * 
	 *  errorInfoSave.  
	 *  @Description：分组报错保存
	 *  @Author WENYI
	 *  @param json 
	 *  @Date:2017年9月19日下午8:10:44
	 */
	private void errorInfoSave(String json,String errInfo){
		String filename = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
		String	filePath= DrgServiceGroupFacadeImpl.class.getClassLoader().getResource("").getPath()+"drgsDataLog/mrGroupData_"+filename+".txt"; 
		
		File jsonfile = new File(filePath); 
		File fileParent = jsonfile.getParentFile();  
		if(!fileParent.exists()&&!fileParent.isDirectory()){
		    fileParent.mkdirs();  
		}
		if(fileParent.exists()&&!fileParent.isDirectory()){
			fileParent.delete();
		    fileParent.mkdirs();  
		}
		// 如果文件夹不存在则创建
		if (!jsonfile.exists()) {
			// 新建文件
			try {
				jsonfile.createNewFile();
			} catch (IOException em) {
				em.printStackTrace();
			}
		}
		FileWriter fw = null;
		PrintWriter out = null;
		try {
			fw = new FileWriter(jsonfile,true);//设为true，追加内容，不覆盖
			out = new PrintWriter(fw);
			out.write(json+ "\n");
			out.write(errInfo+"\n");
			out.println();
		} catch (IOException eo) {
			eo.printStackTrace();
		} finally {
			if (out != null)
				out.close();
			try {
				if (fw != null)
					fw.close();
			} catch (IOException ep) {
				ep.printStackTrace();
			}
		}
	}
}
